package com.agileboot.domain.performance.teaching;

import com.agileboot.common.core.page.PageDTO;
import com.agileboot.domain.performance.teaching.command.AddTeachingWorkloadCommand;
import com.agileboot.domain.performance.teaching.command.UpdateTeachingWorkloadCommand;
import com.agileboot.domain.performance.teaching.db.TeachingWorkloadEntity;
import com.agileboot.domain.performance.teaching.db.TeachingWorkloadService;
import com.agileboot.domain.performance.teaching.dto.TeachingWorkloadDTO;
import com.agileboot.domain.performance.teaching.dto.TeachingWorkloadImportResultDTO;
import com.agileboot.domain.performance.teaching.dto.TeachingWorkloadImportTemplateDTO;
import com.agileboot.domain.performance.teaching.model.TeachingWorkloadModel;
import com.agileboot.domain.performance.teaching.model.TeachingWorkloadModelFactory;
import com.agileboot.domain.performance.teaching.query.TeachingWorkloadQuery;
import com.agileboot.domain.system.dept.db.SysDeptEntity;
import com.agileboot.domain.system.dept.db.SysDeptService;
import com.agileboot.domain.system.user.db.SysUserEntity;
import com.agileboot.domain.system.user.db.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 教学工作量应用服务类
 */
@Service
@RequiredArgsConstructor
public class TeachingWorkloadApplicationService {

    private final TeachingWorkloadModelFactory teachingWorkloadModelFactory;
    private final TeachingWorkloadService teachingWorkloadService;
    private final SysUserService sysUserService;
    private final SysDeptService sysDeptService;

    public PageDTO<TeachingWorkloadDTO> getTeachingWorkloadList(TeachingWorkloadQuery query) {
        Page<TeachingWorkloadEntity> page = teachingWorkloadService.page(query.toPage(), query.toQueryWrapper());
        List<TeachingWorkloadDTO> records = convertEntitiesToDTOs(page.getRecords());
        return new PageDTO<>(records, page.getTotal());
    }

    public TeachingWorkloadDTO getTeachingWorkloadInfo(Long id) {
        TeachingWorkloadEntity entity = teachingWorkloadService.getById(id);
        if (entity == null) {
            return null;
        }
        return convertEntitiesToDTOs(List.of(entity)).get(0);
    }

    public void addTeachingWorkload(AddTeachingWorkloadCommand addCommand) {
        TeachingWorkloadModel model = teachingWorkloadModelFactory.create();
        model.loadFromAddCommand(addCommand);
        
        // 根据userId查询用户信息，获取deptId并设置
        if (addCommand.getUserId() != null) {
            SysUserEntity user = sysUserService.getById(addCommand.getUserId());
            if (user != null && user.getDeptId() != null) {
                model.setDeptId(user.getDeptId());
            }
        }
        
        model.insert();
    }

    public void updateTeachingWorkload(UpdateTeachingWorkloadCommand updateCommand) {
        TeachingWorkloadModel model = teachingWorkloadModelFactory.loadById(updateCommand.getId());
        model.loadFromUpdateCommand(updateCommand);
        model.updateById();
    }

    public void deleteTeachingWorkload(List<Long> ids) {
        teachingWorkloadService.removeBatchByIds(ids);
    }

    /**
     * 获取所有教学工作量列表
     */
    public List<TeachingWorkloadDTO> getTeachingWorkloadListAll(TeachingWorkloadQuery query) {
        List<TeachingWorkloadEntity> all = teachingWorkloadService.list(query.toQueryWrapper());
        return convertEntitiesToDTOs(all);
    }

    /**
     * 将实体列表转换为DTO列表，并填充用户名称和部门名称信息
     * @param entities TeachingWorkloadEntity列表
     * @return TeachingWorkloadDTO列表
     */
    private List<TeachingWorkloadDTO> convertEntitiesToDTOs(List<TeachingWorkloadEntity> entities) {
        if (entities.isEmpty()) {
            return Collections.emptyList();
        }

        // 收集所有需要查询的用户ID
        Set<Long> userIds = entities.stream()
                .filter(Objects::nonNull)
                .flatMap(entity -> Stream.of(entity.getUserId(), entity.getImportedByUserId()))
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        // 批量获取用户信息
        Map<Long, SysUserEntity> userMap;
        if (!userIds.isEmpty()) {
            List<SysUserEntity> userEntities = sysUserService.getByUserIds(new ArrayList<>(userIds));
            userMap = userEntities.stream()
                    .filter(user -> user != null)
                    .collect(Collectors.toMap(
                            SysUserEntity::getUserId,
                            user -> user,
                            (existing, replacement) -> existing
                    ));
        } else {
            userMap = Collections.emptyMap();
        }

        // 从用户信息中收集部门ID
        Set<Long> deptIds = userMap.values().stream()
                .filter(user -> user.getDeptId() != null)
                .map(SysUserEntity::getDeptId)
                .collect(Collectors.toSet());

        // 批量获取部门信息
        Map<Long, SysDeptEntity> deptMap;
        if (!deptIds.isEmpty()) {
            List<SysDeptEntity> deptEntities = sysDeptService.getByDeptIds(new ArrayList<>(deptIds));
            deptMap = deptEntities.stream()
                    .filter(dept -> dept != null)
                    .collect(Collectors.toMap(
                            SysDeptEntity::getDeptId,
                            dept -> dept,
                            (existing, replacement) -> existing
                    ));
        } else {
            deptMap = Collections.emptyMap();
        }

        // 转换为DTO并填充用户名称和部门名称
        final Map<Long, SysUserEntity> finalUserMap = userMap;
        final Map<Long, SysDeptEntity> finalDeptMap = deptMap;
        return entities.stream().map(entity -> {
            TeachingWorkloadDTO dto = new TeachingWorkloadDTO(entity);

            // 设置用户姓名和部门名称
            if (entity.getUserId() != null) {
                SysUserEntity user = finalUserMap.get(entity.getUserId());
                if (user != null) {
                    dto.setUserName(user.getNickname());
                    
                    // 根据用户的部门ID设置部门名称
                    if (user.getDeptId() != null) {
                        SysDeptEntity dept = finalDeptMap.get(user.getDeptId());
                        if (dept != null) {
                            dto.setDeptName(dept.getDeptName());
                        }
                    }
                }
            }

            if (entity.getImportedByUserId() != null) {
                SysUserEntity operator = finalUserMap.get(entity.getImportedByUserId());
                if (operator != null) {
                    dto.setImportedByUserName(operator.getNickname());
                }
            }

            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取导入模板数据
     * 返回所有未删除用户的信息，考核年度自动填入当前年份
     * @return 导入模板数据列表
     */
    public List<TeachingWorkloadImportTemplateDTO> getImportTemplate() {
        // 查询所有未删除的用户
        QueryWrapper<SysUserEntity> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("deleted", 0);
        List<SysUserEntity> users = sysUserService.list(userQueryWrapper);

        if (users.isEmpty()) {
            return Collections.emptyList();
        }

        // 收集部门ID
        Set<Long> deptIds = users.stream()
                .filter(user -> user.getDeptId() != null)
                .map(SysUserEntity::getDeptId)
                .collect(Collectors.toSet());

        // 批量获取部门信息
        Map<Long, SysDeptEntity> deptMap;
        if (!deptIds.isEmpty()) {
            List<SysDeptEntity> deptEntities = sysDeptService.getByDeptIds(new ArrayList<>(deptIds));
            deptMap = deptEntities.stream()
                    .filter(dept -> dept != null)
                    .collect(Collectors.toMap(
                            SysDeptEntity::getDeptId,
                            dept -> dept,
                            (existing, replacement) -> existing
                    ));
        } else {
            deptMap = Collections.emptyMap();
        }

        // 获取当前年份
        int currentYear = LocalDateTime.now().getYear();

        // 转换为模板DTO
        final Map<Long, SysDeptEntity> finalDeptMap = deptMap;
        return users.stream().map(user -> {
            TeachingWorkloadImportTemplateDTO template = new TeachingWorkloadImportTemplateDTO();
            template.setUserId(user.getUserId());
            template.setNickname(user.getNickname());
            template.setAssessmentYear(currentYear);

            // 设置部门名称
            if (user.getDeptId() != null) {
                SysDeptEntity dept = finalDeptMap.get(user.getDeptId());
                if (dept != null) {
                    template.setDeptName(dept.getDeptName());
                }
            }

            return template;
        }).collect(Collectors.toList());
    }

    /**
     * 批量导入教学工作量
     * 如果该用户的数据已存在（userId + assessmentYear），则覆盖，否则新增
     * @param importDataList 导入数据列表
     * @param importedByUserId 导入操作人ID
     * @return 导入结果
     */
    @Transactional(rollbackFor = Exception.class)
    public TeachingWorkloadImportResultDTO batchImport(List<TeachingWorkloadImportTemplateDTO> importDataList, Long importedByUserId) {
        TeachingWorkloadImportResultDTO result = new TeachingWorkloadImportResultDTO();
        List<TeachingWorkloadImportResultDTO.ImportFailureDetail> failureDetails = new ArrayList<>();
        int successCount = 0;
        int failCount = 0;

        if (importDataList == null || importDataList.isEmpty()) {
            result.setSuccessCount(0);
            result.setFailCount(0);
            result.setFailureDetails(Collections.emptyList());
            return result;
        }

        // 获取当前时间字符串
        String importedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        // 1. 批量查询所有现有数据，构建 userId-assessmentYear -> Entity 的映射
        List<TeachingWorkloadEntity> allExistingRecords = teachingWorkloadService.list();
        Map<String, TeachingWorkloadEntity> existingDataMap = allExistingRecords.stream()
                .filter(entity -> entity.getUserId() != null && entity.getAssessmentYear() != null)
                .collect(Collectors.toMap(
                        entity -> entity.getUserId() + "-" + entity.getAssessmentYear(),
                        entity -> entity,
                        (existing, replacement) -> existing
                ));

        // 2. 收集所有需要查询的用户ID，批量获取用户信息
        Set<Long> userIds = importDataList.stream()
                .filter(data -> data != null && data.getUserId() != null)
                .map(TeachingWorkloadImportTemplateDTO::getUserId)
                .collect(Collectors.toSet());

        Map<Long, SysUserEntity> userMap;
        if (!userIds.isEmpty()) {
            List<SysUserEntity> userEntities = sysUserService.getByUserIds(new ArrayList<>(userIds));
            userMap = userEntities.stream()
                    .filter(user -> user != null)
                    .collect(Collectors.toMap(
                            SysUserEntity::getUserId,
                            user -> user,
                            (existing, replacement) -> existing
                    ));
        } else {
            userMap = Collections.emptyMap();
        }

        // 3. 分类处理：收集需要新增和更新的数据
        List<TeachingWorkloadEntity> entitiesToInsert = new ArrayList<>();
        List<TeachingWorkloadEntity> entitiesToUpdate = new ArrayList<>();

        for (int i = 0; i < importDataList.size(); i++) {
            TeachingWorkloadImportTemplateDTO importData = importDataList.get(i);
            int rowNumber = i + 2; // Excel行号从2开始（第1行是标题）

            try {
                // 验证数据
                String validationError = validateImportData(importData);
                if (validationError != null) {
                    failCount++;
                    failureDetails.add(createFailureDetail(rowNumber, importData, validationError));
                    continue;
                }

                // 验证用户是否存在
                SysUserEntity user = userMap.get(importData.getUserId());
                if (user == null || user.getDeptId() == null) {
                    failCount++;
                    failureDetails.add(createFailureDetail(rowNumber, importData, "用户ID不存在或用户已被删除"));
                    continue;
                }

                // 构建唯一标识 key
                String uniqueKey = importData.getUserId() + "-" + importData.getAssessmentYear();
                
                // 计算分数
                double generalCourseScore = importData.getGeneralCourseScore() != null ? importData.getGeneralCourseScore() : 0.0;
                double subjectCourseScore = importData.getSubjectCourseScore() != null ? importData.getSubjectCourseScore() : 0.0;
                double labCourseScore = importData.getLabCourseScore() != null ? importData.getLabCourseScore() : 0.0;
                double totalScore = generalCourseScore + subjectCourseScore + labCourseScore;

                // 判断是新增还是更新
                TeachingWorkloadEntity existingEntity = existingDataMap.get(uniqueKey);
                if (existingEntity != null) {
                    // 更新现有数据
                    existingEntity.setGeneralCourseScore(generalCourseScore);
                    existingEntity.setSubjectCourseScore(subjectCourseScore);
                    existingEntity.setLabCourseScore(labCourseScore);
                    existingEntity.setTotalTeachingScore(totalScore);
                    existingEntity.setImportedAt(importedAt);
                    existingEntity.setImportedByUserId(importedByUserId);
                    existingEntity.setDeptId(user.getDeptId());
                    entitiesToUpdate.add(existingEntity);
                } else {
                    // 新增数据
                    TeachingWorkloadEntity newEntity = new TeachingWorkloadEntity();
                    newEntity.setUserId(importData.getUserId());
                    newEntity.setAssessmentYear(importData.getAssessmentYear());
                    newEntity.setGeneralCourseScore(generalCourseScore);
                    newEntity.setSubjectCourseScore(subjectCourseScore);
                    newEntity.setLabCourseScore(labCourseScore);
                    newEntity.setTotalTeachingScore(totalScore);
                    newEntity.setImportedAt(importedAt);
                    newEntity.setImportedByUserId(importedByUserId);
                    newEntity.setDeptId(user.getDeptId());
                    entitiesToInsert.add(newEntity);
                }

                successCount++;

            } catch (Exception e) {
                failCount++;
                failureDetails.add(createFailureDetail(rowNumber, importData, "导入失败: " + e.getMessage()));
            }
        }

        // 4. 批量插入和批量更新
        if (!entitiesToInsert.isEmpty()) {
            teachingWorkloadService.saveBatch(entitiesToInsert);
        }
        if (!entitiesToUpdate.isEmpty()) {
            teachingWorkloadService.updateBatchById(entitiesToUpdate);
        }

        result.setSuccessCount(successCount);
        result.setFailCount(failCount);
        result.setFailureDetails(failureDetails);

        return result;
    }

    /**
     * 验证导入数据
     * @param importData 导入数据
     * @return 验证错误信息，如果验证通过返回null
     */
    private String validateImportData(TeachingWorkloadImportTemplateDTO importData) {
        if (importData.getUserId() == null) {
            return "用户ID不能为空";
        }

        if (importData.getAssessmentYear() == null) {
            return "考核年度不能为空";
        }

        // 验证分数不能为负数
        if (importData.getGeneralCourseScore() != null && importData.getGeneralCourseScore() < 0) {
            return "通用课程分数不能为负数";
        }

        if (importData.getSubjectCourseScore() != null && importData.getSubjectCourseScore() < 0) {
            return "专业课程分数不能为负数";
        }

        if (importData.getLabCourseScore() != null && importData.getLabCourseScore() < 0) {
            return "实验课程分数不能为负数";
        }

        return null;
    }

    /**
     * 创建失败详情
     */
    private TeachingWorkloadImportResultDTO.ImportFailureDetail createFailureDetail(
            int rowNumber, TeachingWorkloadImportTemplateDTO importData, String failureReason) {
        TeachingWorkloadImportResultDTO.ImportFailureDetail detail = 
                new TeachingWorkloadImportResultDTO.ImportFailureDetail();
        detail.setRowNumber(rowNumber);
        detail.setUserId(importData.getUserId());
        detail.setNickname(importData.getNickname());
        detail.setFailureReason(failureReason);
        detail.setData(importData);
        return detail;
    }
}
